﻿using System.Linq;
using CID.Domain.Development;
using CID.Domain.Infrastructure;
using CID.Domain.Users;
using CID.Execution.Controller.Exceptions;
using CID.Execution.Support.PackageRegistration;
using NailsFramework.IoC;
using NailsFramework.Persistence;

namespace CID.Execution.Controller.PackageRegistration
{
    [Lemming]
    public class PackageRegistrator : IPackageRegistrator
    {
        [Inject]
        public IBag<User> Users { private get; set; }
    
        [Inject]
        public IBag<Component> Components { private get; set; }

        [Inject]
        public IBag<PackageType> PackageTypes { private get; set; }

        public void RegisterPackage(int componentId, int versionId, int packageTypeId, int responsibleId, byte[] content, string comments)
        {
            var component = Components.GetById(componentId);
            if (component == null) throw new InvalidPackageRegistrationException("Component");
            var version = component.Versions.SingleOrDefault(x => x.Id == versionId);
            var packageType = PackageTypes.GetById(packageTypeId);
            var responsible = Users.GetById(responsibleId);

            RegisterPackage(version, packageType, responsible, content, comments);
        }

        public void RegisterPackage(string componentName, string versionName, string packageTypeName, string responsibleUserName, byte[] content, string comments)
        {
            var component = Components.SingleOrDefault(x => x.Name == componentName);
            if (component == null) throw new InvalidPackageRegistrationException("Component");
            var version = component.Versions.SingleOrDefault(x => x.Name == versionName);
            var packageType = PackageTypes.SingleOrDefault(x => x.Name == packageTypeName);
            var responsible = Users.SingleOrDefault(x => x.UserName == responsibleUserName);

            RegisterPackage(version, packageType, responsible, content, comments);
        }

        private void RegisterPackage(IVersion version, IPackageType packageType, IUser responsible, byte[] content, string comments)
        {
            if (version == null) throw new InvalidPackageRegistrationException("Version");
            if (packageType == null) throw new InvalidPackageRegistrationException("Package Type");
            if (responsible == null) throw new InvalidPackageRegistrationException("User Responsible");
            if (!(responsible.Is(UserRole.ComponentManager) || responsible.Is(UserRole.ReleaseManager) || responsible.Is(UserRole.Operator)))
                throw new UserActionUnauthorizedException("package registration", UserRole.ComponentManager, UserRole.ReleaseManager, UserRole.Operator);

            packageType.CreatePackage(version, content, comments, true);
        }
    }
}
